package com.cityeye.dao;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.cityeye.entity.Department;
import com.cityeye.entity.Mmessage;
import com.cityeye.entity.Patrol;
import com.cityeye.entity.Subissuetype;
import com.cityeye.mmsentity.MsgInbox;
import com.cityeye.search.SearchCriteria;

public class MmessageDao extends AbstractEntityDao<Mmessage> {

	private static SearchCriteria[] criteria;

	public static int STATE_NEW = 0;
	public static int STATE_QU = 1;
	public static int STATE_JIEDAO = 2;
	public static int STATE_COMPLETED = 3;
	public static int STATE_COMPLETED_CONFIRMED = 4;
	public static int STATE_COMPLETED_CONFIRMED_NEG = 5;
	public static int STATE_TRASH = 100;

	public static int TYPE_MMS = 0;
	public static int TYPE_TEXT = 1;

	public static int DEF_NUMPIC_ROW = 4;
	public static int DEF_PIC_SIZE = 160;

	public Mmessage createNewEmptyEntity() {
		return new Mmessage();
	}

	protected Object evalueateProperty(String key, Object valueObj) {
		String idStr = valueObj.toString();

		if (key.equalsIgnoreCase("department")
				|| key.equalsIgnoreCase("qudepartment")) {
			return sf.getCurrentSession().get(Department.class,
					Integer.parseInt(idStr));
		} else if (key.equalsIgnoreCase("patrol")) {
			return sf.getCurrentSession().get(Patrol.class,
					Integer.parseInt(idStr));
		} else if (key.equalsIgnoreCase("subissuetype")) {
			return sf.getCurrentSession().get(Subissuetype.class,
					Integer.parseInt(idStr));
		}

		return valueObj;
	}
	

	public int queryIncomingMsgCount() {
		sf.getCurrentSession().beginTransaction();
		try {
			Criteria c = sf.getCurrentSession()
					.createCriteria(getEntityClass());
			c.setProjection(Projections.rowCount());
			Calendar startToday = Calendar.getInstance();
			startToday.set(Calendar.HOUR_OF_DAY, 0); 
			startToday.set(Calendar.SECOND, 0); 
			startToday.set(Calendar.MINUTE, 0); 
			startToday.set(Calendar.MILLISECOND, 0); 

			Calendar now = Calendar.getInstance();
			
			c.add(Restrictions.between("arrivetime",
					new Date(startToday.getTimeInMillis()),
					new Date(now.getTimeInMillis())));
			Integer count = (Integer) c.uniqueResult();
			return count;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			sf.getCurrentSession().getTransaction().commit();
		}
		return 0;
	}

	public List<Mmessage> fetchExtMsgInbox() {
		try {
			// load msg from mms modem table
			MMSDao extMMSDao = new MMSDao();
			List<MsgInbox> newMsgs = extMMSDao.getNewMessages();
			if (newMsgs.size() < 1)
				return Collections.emptyList();

			List<Mmessage> newMmessages = new ArrayList<Mmessage>();

			int incomingMsgIndex = queryIncomingMsgCount();
			// convert to Mmessage object.
			for (MsgInbox extMsg : newMsgs) {
				Mmessage newMmessage = extMsg.toMmessage(++incomingMsgIndex);
				newMmessages.add(newMmessage);
			}

			if (newMmessages.size() > 0) {
				sf.getCurrentSession().beginTransaction();

				doAdd(newMmessages);
				extMMSDao.deleteMessages(newMsgs);

				sf.getCurrentSession().getTransaction().commit();
			}
			return newMmessages;
		} catch (Throwable ex) {
			ex.printStackTrace();
		}
		return Collections.emptyList();
	}

	public List<Mmessage> getNewMessages() {
		List<Mmessage> result = new ArrayList<Mmessage>();
		sf.getCurrentSession().beginTransaction();
		result = sf.getCurrentSession().createCriteria(Mmessage.class)
				.add(Restrictions.eq("msgstate", STATE_NEW))
				.add(Restrictions.sqlRestriction("ASSIGNED_DEPT_ID=-1")).list();
		sf.getCurrentSession().getTransaction().commit();
		return result;
	}

	public List<Mmessage> getDeptMessageByStatus(Department dept, int status) {
		List<Mmessage> result = new ArrayList<Mmessage>();
		sf.getCurrentSession().beginTransaction();
		result = sf
				.getCurrentSession()
				.createCriteria(Mmessage.class)
				.add(Restrictions.eq("msgstate", status))
				.add(Restrictions.sqlRestriction("ASSIGNED_DEPT_ID="
						+ dept.getId())).list();
		sf.getCurrentSession().getTransaction().commit();
		return result;
	}

	public List<Mmessage> getMMessageByType(Department dept, int msgtype) {
		List<Mmessage> result = new ArrayList<Mmessage>();

		sf.getCurrentSession().beginTransaction();
		result = sf
				.getCurrentSession()
				.createCriteria(Mmessage.class)
				.add(Restrictions.eq("msgtype", msgtype))
				.add(Restrictions.sqlRestriction("ASSIGNED_DEPT_ID="
						+ dept.getId())).list();
		sf.getCurrentSession().getTransaction().commit();
		return result;
	}

	public SearchCriteria[] getSearchCriteria() {
		if (criteria == null) {
			criteria = new SearchCriteria[] {
					new SearchCriteria("Code", SearchCriteria.VT_INT),
					new SearchCriteria("Name", SearchCriteria.VT_STRING),
					new SearchCriteria("Taxable", SearchCriteria.VT_STRING),
					new SearchCriteria("Mobile", SearchCriteria.VT_STRING) };
		}
		return criteria;
	}

	protected Class<Mmessage> getEntityClass() {
		return Mmessage.class;
	}

	protected Order getOrderField() {
		return Order.desc("no");
	}
}
